package tech.aistar.corejava.day04;

import java.util.Arrays;

/**
 * Created by 李雨昂 on 2019/7/18.
 */
public class ArrayUtil {
    public static void main(String[] args) {

        int[] arr = new int[]{1,3,1,3,2,4,2,5,6};
        //int[] temp = delByElement(arr,2);
        int[] temp = delRepeatElement03(arr);
        Arrays.sort(temp);
        for(int t:temp){
            System.out.print(t);
        }

    }
    /**
     *  根据元素进行删除
     * 从arr数组中去删除所有的element
     * @param arr 原数组
     * @param element 需要删除的元素
     * @return 不包含删除的元素的新的数组.
     */
    public static int[] delByElement(int[] arr,int element){
        if(arr == null || arr.length == 0){
            return new int[]{-1};
        }

        int  count = 0;
        for(int i = 0;i < arr.length;i++){
            if(arr[i] == element){
                count++;
            }
        }
        if(count == 0){
            return arr;
        }
        //找新数组长度
        int[] temp = new int[arr.length - count];

        //定义一个新的数组的下标计数器
        int pos = 0;

        //遍历arr
        for(int i = 0;i < arr.length;i++){
            if (arr[i] != element){
                temp[pos++] = arr[i];
            }
        }
        return temp;
    }

    /**
     * 数组排重方式一:
     * @param arr
     * @return
     */
    public static int[] delRepeatElement01(int[] arr){
        //1. 先进行参数的有效性判断
        //数组是否为空[null],数组中是否存在元素
        if(arr == null ||arr.length == 0){
            return new int[]{-1};//心里认为这是一个无效的数组
        }
        //思路:遍历arr,然后拿到一个数,依次拿这个数和它后面的所有数进行比较
        //如果某个位置上面的值和这个数相同,那么就调用根据下标进行删除
        //保证:每次循环走完,后面出现的相同的值都将会被删除
        for(int i = 0;i < arr.length;i++){
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[i] == arr[j]){
                    //将j位删除
                    arr = delByIndex(arr,j);
                    j--;//指针前移保证不会漏掉
                }
            }
        }
        return arr;
    }

    /**
     * 下标是唯一的.
     *
     * 根据下标进行删除
     * @param arr 原数组
     * @param index 需要删除的下标
     * @return 不包含下标index处的值的新的数组
     */
    public static int[] delByIndex(int[] arr,int index){
        //1. 先进行参数的有效性判断
        //数组是否为空[null],数组中是否存在元素
        if(arr == null ||arr.length == 0 || index < 0 || index > arr.length - 1){
            //返回一个信息量出来
            return new int[]{-1};//心里认为这是一个无效的数组
        }

        //2. 确定新的数组长度
        int[] temp = new int [arr.length - 1];

        //定义一个计数器,保证新数组下标连续
        int pos = 0;

        //3. 遍历数组,判断当前下标是否等于index
        //如果不等于就放到新数组里
        for (int i = 0; i < arr.length; i++) {
            if (i != index) {
                temp[pos++] = arr[i];
            }
        }
        return temp;//返回的是
    }

    /**
     * 下标是唯一的.
     *
     *  1 2 2 3 3 4 5 6
     *
     * 根据下标进行删除
     * @param arr 原数组
     * @param index 需要删除的下标
     * @return 不包含下标index处的值的新的数组
     */
    public static int[] delByIndex2(int[] arr, int index){
        //1. 先进行参数的有效性判断
        //数组是否为空[null],数组中是否存在元素.
        if(arr == null || arr.length == 0 || index < 0 || index > arr.length - 1){
            //返回一个信号量出来
            return new int[]{-1};//心里认为这是一个无效的数组.
        }
        //此处对原数组arr进行了直接的操作
        //2. 从index处遍历,后面的值覆盖前面的值
        for(int i = index;i < arr.length;i++){
            arr[i] = arr[i+1];
        }

        //去除最后面的一位
        int[] temp =new int[arr.length - 1];
        for(int i = 0;i < arr.length - 1;i++){
            temp[i] = arr[i];
        }
        return temp;
    }
    public static int[] delRepeatElement02(int[] arr,int index){
        if(arr == null ||arr.length == 0){
            return new int[]{-1};//心里认为这是一个无效的数组
        }

        //1.定义一个和原来数组长度一样的boolean型数组
        boolean[] flags = new boolean[arr.length];

        //2.统一赋值true
        Arrays.fill(flags,true);

        //3.遍历arr
        for(int i = 0;i < arr.length;i++){

            for (int j = i + 1; j < arr.length; j++) {
                if(arr[i] == arr[j]){
                    flags[j] = false;
                }
            }
        }
        //定义计数器来确定新数组长度
        int count = 0;
        for(int i = 0;i < flags.length;i++){
            if(flags[i]){
                count++;
            }
        }
        int[] temp = new int[count];
        //定一下标计数器
        int pos = 0;

        //遍历arr
        for (int i = 0; i < arr.length; i++) {
            if(flags[i]){
                temp[pos++] = arr[i];
            }
        }
        return temp;
    }


    /**
     * {1,3,1,3,2,4,2,5,6}; - arr
     * {1,0,0,0,0,0,0,0,0}; - temp
     *
     * //1. 先将arr对应的{1,3,1,3,2,4,2,5,6}的第一个元素1直接放入到temp数中  temp[0] = 1
     * //2. 立即到arr中将数字1全部删除 - 我们自己写的根据元素进行删除的方法 - 返回的是新的数组{2,2,2,3,4} - 地址重新赋值给arr
     *      arr - > {3,3,2,4,2,5,6}
     *
     * //3. 将arr[0] 赋值给temp[1] = 2;
     *
     * //4. 过程中注意:arr一直在不停地重新指向一个新的数组
     *      永远将arr指向的那个数组的第一个元素存放到temp中
     *
     *
     *  //5. 一直到arr指向的那个数组的长度为0的时候退出
     *
     *  //6. 处理一下多余的0
     *
     * @param arr
     * @return
     */
    public static int[] delRepeatElement03(int[] arr) {
        if (arr == null || arr.length == 0) {
            //返回一个信号量出来
            return new int[]{-1};//心里认为这是一个无效的数组.
        }

        //
        int[] temp = new int[arr.length];

        //定义一个下标计数器
        int pos = 0;
        do {
            //永远将arr数组中的第一个元素赋值给temp
            //{1,3,1,3,2,4,2,5,6}
            temp[pos++] = arr[0];//temp[0] = 1 ; temp[1] = 3
            arr = delByElement(arr,arr[0]);//删除数组中为arr[0]的元素    {3,3,2,4,2,5,6}
            if(arr.length == 0){
                break;
            }
        }while (true);

        //对多余的0进行处理
        return Arrays.copyOf(temp,pos);
    }
}
